package org.moonshot.cvm;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class CVMBinaryIO
{
	private static final byte[] cvmHeaderProto = {(byte) 0xF9, (byte) 0x2A, (byte) 0xA7, (byte) 0x9B, (byte) 0x33, (byte)0x05};
	
	public void pullHeader(InputStream aStream) throws IOException, CVMRuntimeException
	{
		final byte[] buffer = new byte[cvmHeaderProto.length];
		if( buffer.length != aStream.read (buffer) )
			throw new CVMRuntimeException ("CVM Class file has invalid header");
		
		for(int i = 0; i < buffer.length; i++)
			if( buffer[i] != cvmHeaderProto[i] )
				throw new CVMRuntimeException ("CVM Class file has invalid header");
	}
	
	public void putHeader(OutputStream aStream) throws IOException
	{
		aStream.write (cvmHeaderProto);
	}
	
	public String pullString(InputStream aStream) throws IOException
	{
		int len = pullInt(aStream);
		byte[] bytes = new byte[len];
		aStream.read (bytes);
		return new String(bytes, "UTF8");
	}
	
	public void putString(String aValue, OutputStream aStream) throws IOException
	{
		byte[] bytes = aValue.getBytes ("UTF8");
		putInt(bytes.length, aStream);
		aStream.write (bytes);
	}
	
	public int pullInt (InputStream aStream) throws IOException
    {
	    int p = 1;
		int v = 0;
	    int s = aStream.read ();
	    while( -1 != s && 0 != (s & 0x80) )
	    {
	    	v = v + p * (s & 0x7F);
	    	p = p * 128;
	    	s = aStream.read ();
	    }
	    if( s > -1 ) v = v*128 + s;
	    return v;
    }
	
	public void putInt (int aValue, OutputStream aStream) throws IOException
	{
		int v = aValue;
		while( v > 127 )
		{
			aStream.write (0x80 | v & 0x7F);
			v = v / 128;
		}
		aStream.write (v & 0x7F);
	}
	
	public CVMMethod pullMethod (BufferedInputStream theStream)
    {
	    
		return null;
    }
	
	public String[] pullArray (BufferedInputStream theStream)
    {
	    // TODO Auto-generated method stub
	    return null;
    }
}
